#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : token.py
@Author  : lepal
@Time    : 2024-08-19 10:11
"""
import base64
import json

from flask import current_app, jsonify, request

from app.libs.RedPrint import RedPrint
from app.libs.enums import ClientTypeEnum
from app.libs.error_code import Success
from app.libs.token_auth import validate_token
from app.models.user import User
from app.validators.forms import ClientForm
# from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired, BadSignature
# 从 itsdangerous 的版本 2.0 开始，TimedJSONWebSignatureSerializer 类被移除，取而之的是 TimedSerializer 和 JSONWebSignatureSerializer
from itsdangerous import TimestampSigner, SignatureExpired, BadSignature
from itsdangerous import URLSafeSerializer

api = RedPrint('token')


# 生成token
@api.route('/create_token', methods=['POST'])
def create_token():
    # 验证登录时的参数
    form = ClientForm().validate_for_api()

    promise = {
        ClientTypeEnum.USER_EMAIL: User.verify,   # 通过用户名、密码验证用户是否存在，如果存在返回
    }

    # 定义一个字典  ClientTypeEnum(form.type.data) 的值可能是 USER_EMAIL,
    # 相当于调用ClientTypeEnum.USER_EMAIL();  拿到的返回是用 {'uid': user.id, 'scope': scope}
    user_dict = promise[ClientTypeEnum(form.type.data)](
        form.account.data,
        form.secret.data
    )
    # 生成token
    expiration = current_app.config['TOKEN_EXPIRATION']
    token = generate_auth_token(user_dict['uid'],
                                form.type.data,
                                user_dict['scope'],
                                expiration)


    # 把token拼接上：符号 （因为Http Basic auth 就是这个验证机制），转成byte类型
    auth_token = base64.b64encode((token +':').encode('utf-8'))

    # 这里生成额token是bytes类型，需要decode
    t = {
        # 'token': token.decode('ascii')
        'token': token,
        'auth_token': 'basic ' + auth_token.decode('utf-8')
    }
    return jsonify(t), 200


# 生成令牌 （高版本废弃了 TimedJSONWebSignatureSerializer，自己这里重写）
def generate_auth_token(uid, ac_type, scope=None,
                        expiration=7200):
    """生成令牌"""
    # s = Serializer(current_app.config['SECRET_KEY'],expires_in=expiration)
    # return s.dumps({
    #     'uid': uid,
    #     'type': ac_type.value,
    #     'scope':scope
    # })

    ts = TimestampSigner(current_app.config['SECRET_KEY'])
    url_s = URLSafeSerializer(current_app.config['SECRET_KEY'])
    data = {
        'uid': uid,
        'type': ac_type.value,
        'scope':scope
    }
    # 先签名成带时间戳的bytes
    signed_bytes = ts.sign(json.dumps(data))
    print("带时间戳的",signed_bytes)  # b'{"uid": 3, "type": 100, "scope": 2}.ZsLveA.IBMhzLN0auxWrJjXWUMrmrwcHks'

    # 再把带时间的bytes转成字符串，再通过URLSafeSerializer进行序列化
    token = url_s.dumps(signed_bytes.decode('ascii'))
    print("转成字符串",token) # IntcInVpZFwiOiAzLCBcInR5cGVcIjogMTAwLCBcInNjb3BlXCI6IG51bGx9LlpzTHZlQS5JQk1oekxOMGF1eFdySmpYV1VNcm1yd2NIa3Mi.o2jCDSZ3-g7LXN3hMr2eS9dghtE
    return token


# 验证token
@api.route('/valid_token', methods=['POST'])
def valid_token():
    data = request.get_json()
    user_info = validate_token(data['token'])

    print("user_info",type(user_info))

    return jsonify(user_info), 200


